package cn.dglydrpy.study.spring.ioc.annotation;

import java.io.Serializable;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

/*
 * @Description:用注解进行Spring Bean的注入与生命周期管理  
 *              使用注解管理的javaBean,配置文件里只需写注解扫描包即可,大大简化了配置
 * @author:dglydrpy
 * @date:2019年4月16日 下午11:46:41 
 * @version:1.0
 */
@Component("diyBean")  
//自定义id为diyBean,自定义id后默认id(类名首字母小写)将不存在
//实现接口/继承父类的bean默认也是该实现类/子类类名首字母小写 
//很多标签都能自定义id,根据不同的软件逻辑层次可以用不同的注解(@service @named @Controller...)
//原则:自己写的组件写注解 使用别人给的组件用xml
@Lazy(true) //单例推迟加载
//@Scope("prototype") //默认为单例模式,用scope()可以设置多例(原型)模式
public class AnnotationLifeCycleBean implements Serializable,BeanNameAware,BeanFactoryAware,ApplicationContextAware,
InitializingBean,DisposableBean{
	
	private static final long serialVersionUID = 1L;
	
	@Value("李四") //注入基本值
	private String name; 
	@Value("#{b.age}") //基本值注入,一般和spring表达式配合使用
	private int age;
	private boolean alive;
	
	public AnnotationLifeCycleBean() {
		this.alive = true;
		System.out.println("annotationLifeCycleBean 构造方法实例化:"+this.toString());
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public boolean isAlive() {
		return alive;
	}

	public void setAlive(boolean alive) {
		this.alive = alive;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + (alive ? 1231 : 1237);
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		AnnotationLifeCycleBean other = (AnnotationLifeCycleBean) obj;
		if (age != other.age)
			return false;
		if (alive != other.alive)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "AnnotationLifeCycleBean [name=" + name + ", age=" + age + ", alive=" + alive + "]";
	}
	
	@PostConstruct //构造函数之后,初始化之前执行
	public void initMethod() {
		System.out.println("annotationLifeCycleBean 执行@PostConstruct:"+this.toString());
	}
	
	@PreDestroy
	public void destroyMethod() {
		this.alive = false;
		this.age = 100;
		System.out.println("annotationLifeCycleBean 执行@PreDestroy:"+this.toString());
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("annotationLifeCycleBean 执行 afterPropertiesSet()"); //在@PostConstruct标记的init()后执行
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		System.out.println("annotationLifeCycleBean 高级容器接口applicationContext: " + applicationContext);
		
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		System.out.println("annotationLifeCycleBean 管理我的beanFactory为: " + beanFactory);
		
	}

	@Override
	public void setBeanName(String name) {
		System.out.println("annotationLifeCycleBean 注册我成为bean时定义的id: " + name);
	}

	@Override
	public void destroy() throws Exception {
		System.out.println("annotationLifeCycleBean 执行DisposableBean.destroy()");
	}
}
